package com.lin.manager.quartz.config;

import com.lin.manager.quartz.CustomJobFactory;
import org.quartz.Calendar;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.quartz.JobStoreType;
import org.springframework.boot.autoconfigure.quartz.QuartzProperties;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

/**
 * @作者: 林江
 * @创建时间: 2024/3/24
 * @功能:
 */
@Configuration
@EnableConfigurationProperties(QuartzProperties.class)
public class QuartzConfig {
    private final String quartzPp = "quartz.properties";

    @Bean
    @ConditionalOnMissingBean
    public SchedulerFactoryBean quartzScheduler(QuartzProperties properties,
                                                ObjectProvider<SchedulerFactoryBeanCustomizer> customizers, ObjectProvider<JobDetail> jobDetails,
                                                Map<String, Calendar> calendars, ObjectProvider<Trigger> triggers, ApplicationContext applicationContext) throws IOException {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        // 自定义job的创建工厂
        CustomJobFactory jobFactory = new CustomJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        schedulerFactoryBean.setJobFactory(jobFactory);
        if (properties.getSchedulerName() != null) {
            schedulerFactoryBean.setSchedulerName(properties.getSchedulerName());
        }
        // 程序一旦启动,调度程序就会立即调度.
        schedulerFactoryBean.setAutoStartup(properties.isAutoStartup());
        schedulerFactoryBean.setStartupDelay((int) properties.getStartupDelay().getSeconds());
        schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(properties.isWaitForJobsToCompleteOnShutdown());
        schedulerFactoryBean.setOverwriteExistingJobs(properties.isOverwriteExistingJobs());
        schedulerFactoryBean.setJobDetails(jobDetails.orderedStream().toArray(JobDetail[]::new));
        schedulerFactoryBean.setCalendars(calendars);
        schedulerFactoryBean.setTriggers(triggers.orderedStream().toArray(Trigger[]::new));
        customizers.orderedStream().forEach((customizer) -> customizer.customize(schedulerFactoryBean));

        // 外部数据库配置
        if (properties.getJobStoreType().toString().equalsIgnoreCase(JobStoreType.JDBC.toString())) {
            schedulerFactoryBean.setQuartzProperties(getProperties());
        }

        return schedulerFactoryBean;
    }

    /**
     * 手动读取quartz资源
     *
     * @return
     * @throws IOException
     */
    public Properties getProperties() throws IOException {
        Properties properties = new Properties();
        InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(quartzPp);
        if (stream != null) {
            properties.load(stream);
        }
        return properties;
    }
}
